home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Format 1995 June
/
MacFormat 25.iso
/
Shareware City
/
Developers
/
OutOfPhase1.1 Source
/
OutOfPhase Folder
/
SampleOscControl.c
< prev
next >
Wrap
Text File
|
1995-01-04
|
67KB
|
1,970 lines
/* SampleOscControl.c */
/*****************************************************************************/
/* */
/* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
/* Copyright (C) 1994 Thomas R. Lawrence */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
/* */
/*****************************************************************************/
#include "MiscInfo.h"
#include "Audit.h"
#include "Debug.h"
#include "Definitions.h"
#include "SampleOscControl.h"
#include "64BitMath.h"
#include "Multisampler.h"
#include "EnvelopeState.h"
#include "Envelope.h"
#include "LFOGenerator.h"
#include "LFOListSpecifier.h"
#include "SampleConsts.h"
#include "Memory.h"
#include "OscillatorSpecifier.h"
#include "ErrorDaemon.h"
#if !MEMDEBUG && DEBUG
#undef PRNGCHK
#define PRNGCHK(x,y,z) ((void)0)
#endif
/* prototypes for fast playback routines */
static void Sample_MonoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_MonoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_MonoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_MonoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_MonoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_MonoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_MonoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_MonoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_StereoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
static void Sample_NoOutput(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
/* this is used for loop control */
typedef enum
{
eRepeatingLoop1 EXECUTE(= -18734),
eRepeatingLoop2,
eRepeatingLoop3,
eNoLoop,
eSampleFinished
} LoopType;
/* sample oscillator template information record */
struct SampleTemplateRec
{
/* source information for the sample */
MultiSampleRec* SampleSourceSelector;
/* sampling rate for final output */
long FinalOutputSamplingRate;
/* number of envelope updates per second */
float EnvelopeTicksPerSecond;
/* values for scaling the frequency of something. if we were really serious about */
/* this, we'd traverse all of the oscillators with integral multiples or harmonic */
/* fractions of the pitch & set their differentials to the same precision as the */
/* worst oscillator so that they would all stay in sync as time progressed. */
float FrequencyMultiplier;
/* this is added after the frequency multiplier is applied */
float FrequencyAdder;
/* stereo status */
NumChannelsType StereoPlayback;
/* time interpolation flag */
MyBoolean InterpolateThroughTime;
/* inter-wave interpolation flag */
MyBoolean InterpolateAcrossWaves; /* not used now -- for future use */
/* envelope templates */
EnvelopeRec* LoudnessEnvelopeTemplate;
LFOListSpecRec* LoudnessLFOTemplate;
/* miscellaneous control parameters */
float StereoBias;
float TimeDisplacement;
float OverallOscillatorLoudness;
/* error logging facility */
ErrorDaemonRec* ErrorDaemon;
/* template for the pitch displacement LFO */
LFOListSpecRec* PitchLFOTemplate;
/* link for list control */
SampleTemplateRec* Next;
};
/* sample oscillator state record */
struct SampleStateRec
{
/* current sample position into the array */
LongLongRec SamplePosition; /* 32-bit fixed point */
/* current increment value for the sample position */
LongLongRec SamplePositionDifferential; /* 32-bit fixed point */
/* envelope tick countdown for pre-start time */
long PreStartCountdown;
/* function for generating a bunch of sample points */
void (*SampleGenSamples)(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer);
/* number of frames in the sample */
long NumFrames;
/* sample data pointer. for mono, it is just an array. for stereo, the */
/* samples are interleaved, left channel first */
void* Data;
/* number of bits in the data for the sample */
NumBitsType NumBits;
/* stereo or mono sample */
NumChannelsType NumChannels;
/* control parameters for the sample */
float NaturalFrequency;
long SamplingRate;
long OriginPoint;
long Loop1Start;
long Loop2Start;
long Loop3Start;
long Loop1End;
long Loop2End;
long Loop3End;
/* state information for the current position */
LoopType LoopState; /* which loop is running */
long CurrentLoopLength; /* current loop length (end - start) */
long CurrentLoopEnd; /* current loop/total end point */
/* NOTE: either OverallLoudness or Left/RightLoudness are used, but not both */
/* current overall loudness for oscillator */
FastFixedType OverallLoudness; /* 15-bit fixed point, 0..1 */
/* left channel loudness */
FastFixedType LeftLoudness; /* 15-bit fixed point, 0..1 */
/* right channel loudness */
FastFixedType RightLoudness; /* 15-bit fixed point, 0..1 */
/* panning position for splitting envelope generator into stereo channels */
/* 0 = left channel, 0.5 = middle, 1 = right channel */
FastFixedType Panning; /* 15-bit fixed point, 0..1 */
/* envelope that is generating the loudness information */
EvalEnvelopeRec* SampleLoudnessEnvelope;
/* LFO generators modifying the output of the loudness envelope generator */
LFOGenRec* LoudnessLFOGenerator;
/* this flag is True if the sample data was defined at the specified pitch */
/* (and the sample vectors are thus valid) or False if there is no sample */
/* at this pitch (and the arrays are invalid) */
MyBoolean SampleWasDefined;
/* this field contains the overall volume scaling for everything so that we */
/* can treat the envelopes as always going between 0 and 1. */
float NoteLoudnessScaling;
/* this calculates the differential values for periodic pitch displacements */
LFOGenRec* PitchLFO;
/* pitch lfo startup counter; negative = expired */
long PitchLFOStartCountdown;
/* static information for the sample */
SampleTemplateRec Template; /* a copy of the data */
/* link for list control */
SampleStateRec* Next;
};
static SampleTemplateRec* SampleTemplateFreeList = NIL;
static SampleStateRec* SampleStateFreeList = NIL;
/* get rid of all cached memory for state or template records */
void FlushSampleOscControl(void)
{
while (SampleTemplateFreeList != NIL)
{
SampleTemplateRec* Temp;
Temp = SampleTemplateFreeList;
SampleTemplateFreeList = SampleTemplateFreeList->Next;
ReleasePtr((char*)Temp);
}
while (SampleStateFreeList != NIL)
{
SampleStateRec* Temp;
Temp = SampleStateFreeList;
SampleStateFreeList = SampleStateFreeList->Next;
ReleasePtr((char*)Temp);
}
}
#if DEBUG
static void CheckValidSampleTemplate(SampleTemplateRec* Object)
{
SampleTemplateRec* Scan;
Scan = SampleTemplateFreeList;
while (Scan != NIL)
{
if (Scan == Object)
{
PRERR(ForceAbort,"CheckValidSampleTemplate: template is on free list");
}
Scan = Scan->Next;
}
}
#else
#define CheckValidSampleTemplate(x) ((void)0)
#endif
#if DEBUG
static void CheckValidSampleState(SampleStateRec* Object)
{
SampleStateRec* Scan;
Scan = SampleStateFreeList;
while (Scan != NIL)
{
if (Scan == Object)
{
PRERR(ForceAbort,"CheckValidSampleState: state is on free list");
}
Scan = Scan->Next;
}
}
#else
#define CheckValidSampleState(x) ((void)0)
#endif
/* perform one envelope update cycle */
void UpdateSampleEnvelopes(SampleStateRec* State)
{
FastFixedType Temp;
CheckPtrExistence(State);
CheckValidSampleState(State);
/* this is for the benefit of resampling only -- envelope generators do their */
/* own pre-origin sequencing */
if (State->PreStartCountdown > 0)
{
State->PreStartCountdown -= 1;
}
Temp = State->NoteLoudnessScaling * LFOGenUpdateCycle(State->LoudnessLFOGenerator,
EnvelopeUpdate(State->SampleLoudnessEnvelope));
/* fast fixed has a very narrow range, so overflow can't be permitted: */
/* 15x15->30 bits, with 2 extra bits; we use one for sign and the other */
/* to permit the representation of 1 and -1. */
if (State->Template.StereoPlayback == eSampleMono)
{
if (Temp < - Int2FastFixed(1))
{
ErrorDaemonReportClamping(State->Template.ErrorDaemon,
- FastFixed2Float(Temp));
Temp = - Int2FastFixed(1);
}
else if (Temp > Int2FastFixed(1))
{
ErrorDaemonReportClamping(State->Template.ErrorDaemon,
FastFixed2Float(Temp));
Temp = Int2FastFixed(1);
}
State->OverallLoudness = Temp;
}
else
{
FastFixedType LeftVolumeScaling;
FastFixedType RightVolumeScaling;
FastFixedType MaxVolScaling;
FastFixedType MaxTemp;
LeftVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
Int2FastFixed(1) - State->Panning);
RightVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
Int2FastFixed(1) + State->Panning);
if (((LeftVolumeScaling >= 0) ? LeftVolumeScaling : (- LeftVolumeScaling))
> ((RightVolumeScaling >= 0) ? RightVolumeScaling : (- RightVolumeScaling)))
{
MaxVolScaling = ((LeftVolumeScaling >= 0)
? LeftVolumeScaling : (- LeftVolumeScaling));
}
else
{
MaxVolScaling = ((RightVolumeScaling >= 0)
? RightVolumeScaling : (- RightVolumeScaling));
}
MaxTemp = Double2FastFixed((float)1 / FastFixed2Float(MaxVolScaling));
if (Temp < - MaxTemp)
{
ErrorDaemonReportClamping(State->Template.ErrorDaemon,
- FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
Temp = - MaxTemp;
}
else if (Temp > MaxTemp)
{
ErrorDaemonReportClamping(State->Template.ErrorDaemon,
FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
Temp = MaxTemp;
}
State->LeftLoudness = FastFixedTimesFastFixedToFastFixed(
LeftVolumeScaling,Temp);
State->RightLoudness = FastFixedTimesFastFixedToFastFixed(
RightVolumeScaling,Temp);
}
}
/* dispose of the sample state record */
void DisposeSampleState(SampleStateRec* State)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
DisposeEnvelopeStateRecord(State->SampleLoudnessEnvelope);
DisposeLFOGenerator(State->LoudnessLFOGenerator);
DisposeLFOGenerator(State->PitchLFO);
State->Next = SampleStateFreeList;
SampleStateFreeList = State;
}
/* dispose of the sample information template */
void DisposeSampleTemplate(SampleTemplateRec* Template)
{
CheckPtrExistence(Template);
CheckValidSampleTemplate(Template);
DisposeMultisample(Template->SampleSourceSelector);
Template->Next = SampleTemplateFreeList;
SampleTemplateFreeList = Template;
}
/* create a new sample template */
SampleTemplateRec* NewSampleTemplate(struct OscillatorRec* Oscillator,
float EnvelopeTicksPerSecond, long SamplingRate,
MyBoolean Stereo, MyBoolean TimeInterp, MyBoolean WaveInterp,
ErrorDaemonRec* ErrorDaemon)
{
SampleTemplateRec* Template;
CheckPtrExistence(ErrorDaemon);
CheckPtrExistence(Oscillator);
ERROR(OscillatorGetWhatKindItIs(Oscillator) != eOscillatorSampled,PRERR(ForceAbort,
"NewSampleTemplate: oscillator is not a sample"));
if (SampleTemplateFreeList != NIL)
{
Template = SampleTemplateFreeList;
SampleTemplateFreeList = SampleTemplateFreeList->Next;
}
else
{
Template = (SampleTemplateRec*)AllocPtrCanFail(sizeof(SampleTemplateRec),
"SampleTemplateRec");
if (Template == NIL)
{
return NIL;
}
}
EXECUTE(Template->Next = (SampleTemplateRec*)0x81818181;)
Template->SampleSourceSelector = NewMultisampleSample(
OscillatorGetSampleIntervalList(Oscillator));
if (Template->SampleSourceSelector == NIL)
{
FailurePoint1:
Template->Next = SampleTemplateFreeList;
SampleTemplateFreeList = Template;
return NIL;
}
Template->FinalOutputSamplingRate = SamplingRate;
Template->EnvelopeTicksPerSecond = EnvelopeTicksPerSecond;
/* it might be better to handle divisor and multiplier separately -- we would */
/* want to do that if we were trying to guarantee that all harmonic */
/* oscillators ran in lock-step */
Template->FrequencyMultiplier = OscillatorGetFrequencyMultiplier(Oscillator)
/ OscillatorGetFrequencyDivisor(Oscillator);
Template->FrequencyAdder = OscillatorGetFrequencyAdder(Oscillator);
Template->StereoBias = OscillatorGetStereoBias(Oscillator);
Template->TimeDisplacement = OscillatorGetTimeDisplacement(Oscillator);
Template->OverallOscillatorLoudness = OscillatorGetOutputLoudness(Oscillator);
if (Stereo)
{
Template->StereoPlayback = eSampleStereo;
}
else
{
Template->StereoPlayback = eSampleMono;
}
Template->InterpolateThroughTime = TimeInterp;
Template->InterpolateAcrossWaves = WaveInterp;
/* these are just references */
Template->LoudnessEnvelopeTemplate = OscillatorGetLoudnessEnvelope(Oscillator);
Template->LoudnessLFOTemplate = OscillatorGetLoudnessLFOList(Oscillator);
/* more references */
Template->ErrorDaemon = ErrorDaemon;
Template->PitchLFOTemplate = GetOscillatorFrequencyLFOList(Oscillator);
return Template;
}
/* create a new sample state object. */
SampleStateRec* NewSampleState(SampleTemplateRec* Template,
float FreqForMultisampling, float Accent1, float Accent2,
float Accent3, float Accent4, float Loudness, float HurryUp,
long* PreOriginTimeOut, float StereoPosition,
float InitialFrequency, float PitchDisplacementDepthLimit,
float PitchDisplacementRateLimit,
long PitchDisplacementStartPoint)
{
SampleStateRec* State;
long MaxPreOrigin;
long OnePreOrigin;
double NaturalFreqTemp;
CheckPtrExistence(Template);
CheckValidSampleTemplate(Template);
if (SampleStateFreeList != NIL)
{
State = SampleStateFreeList;
SampleStateFreeList = SampleStateFreeList->Next;
}
else
{
State = (SampleStateRec*)AllocPtrCanFail(sizeof(SampleStateRec),
"SampleStateRec");
if (State == NIL)
{
FailurePoint1:
return NIL;
}
}
EXECUTE(State->Next = (SampleStateRec*)0x81818181;)
State->Template = *Template;
MaxPreOrigin = 0;
Double2LongLong(0,&(State->SamplePosition));
/* State->SamplePositionDifferential is specified in a separate call */
State->NoteLoudnessScaling = Loudness * Template->OverallOscillatorLoudness;
State->SampleWasDefined = GetMultisampleReferenceSample(
Template->SampleSourceSelector,FreqForMultisampling,&(State->Data),
&(State->NumFrames),&(State->NumBits),&(State->NumChannels),&(State->Loop1Start),
&(State->Loop1End),&(State->Loop2Start),&(State->Loop2End),&(State->Loop3Start),
&(State->Loop3End),&(State->OriginPoint),&NaturalFreqTemp,&(State->SamplingRate));
if (State->SampleWasDefined && (State->NumFrames > 0))
{
/* copy value over */
State->NaturalFrequency = NaturalFreqTemp;
/* bounds checking */
if (State->Loop1Start < 0)
{
State->Loop1Start = 0;
}
if (State->Loop1End > State->NumFrames - 1)
{
State->Loop1End = State->NumFrames - 1;
}
if (State->Loop1End < State->Loop1Start)
{
State->Loop1End = State->Loop1Start;
}
if (State->Loop2Start < 0)
{
State->Loop2Start = 0;
}
if (State->Loop2End > State->NumFrames - 1)
{
State->Loop2End = State->NumFrames - 1;
}
if (State->Loop2End < State->Loop2Start)
{
State->Loop2End = State->Loop2Start;
}
if (State->Loop3Start < 0)
{
State->Loop3Start = 0;
}
if (State->Loop3End > State->NumFrames - 1)
{
State->Loop3End = State->NumFrames - 1;
}
if (State->Loop3End < State->Loop3Start)
{
State->Loop3End = State->Loop3Start;
}
/* set the initial state */
if (State->Loop1Start != State->Loop1End)
{
State->LoopState = eRepeatingLoop1;
State->CurrentLoopEnd = State->Loop1End;
State->CurrentLoopLength = State->Loop1End - State->Loop1Start;
}
else if (State->Loop2Start != State->Loop2End)
{
State->LoopState = eRepeatingLoop2;
State->CurrentLoopEnd = State->Loop2End;
State->CurrentLoopLength = State->Loop2End - State->Loop2Start;
}
else if (State->Loop3Start != State->Loop3End)
{
State->LoopState = eRepeatingLoop3;
State->CurrentLoopEnd = State->Loop3End;
State->CurrentLoopLength = State->Loop3End - State->Loop3Start;
}
else
{
State->LoopState = eNoLoop;
State->CurrentLoopEnd = State->NumFrames;
State->CurrentLoopLength = 0;
}
/* compute how much time to wait before starting sample playback. this */
/* is INDEPENDENT of the envelope starting points; the envelope generator setup */
/* handles origin alignment on its own. */
/* this number will assume the origin starts NOW. the fixup routine will */
/* add some number to this so that the origin is properly determined. */
/* if the countdown is still negative, then the sample will sound like it */
/* is starting late. the user can fix this by increasing the scanning gap. */
State->PreStartCountdown = - (
((((float)State->OriginPoint / ((InitialFrequency
* Template->FrequencyMultiplier + Template->FrequencyAdder)
/ State->NaturalFrequency)) / State->SamplingRate)
- Template->TimeDisplacement)
* Template->EnvelopeTicksPerSecond + 0.5);
if (- State->PreStartCountdown > MaxPreOrigin)
{
MaxPreOrigin = - State->PreStartCountdown;
}
}
else
{
/* no playback */
State->LoopState = eSampleFinished;
}
/* State->SampleWasDefined: */
/* if there is no sample defined for the current pitch, then we don't */
/* bother generating any data */
/* State->NumFrames > 0: */
/* if there is no data in the sample, then don't access the array */
if (State->SampleWasDefined && (State->NumFrames > 0))
{
if (Template->StereoPlayback == eSampleStereo) /* this is output stereo */
{
if (State->NumBits == eSample16bit)
{
if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_StereoOut_StereoSamp_16BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_StereoOut_StereoSamp_16BitIn_NoTime;
}
}
else /* sample data mono */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_StereoOut_MonoSamp_16BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_StereoOut_MonoSamp_16BitIn_NoTime;
}
}
}
else /* output 8-bit */
{
if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_StereoOut_StereoSamp_8BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_StereoOut_StereoSamp_8BitIn_NoTime;
}
}
else /* mono sample data */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_StereoOut_MonoSamp_8BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_StereoOut_MonoSamp_8BitIn_NoTime;
}
}
}
}
else /* output mono */
{
if (State->NumBits == eSample16bit)
{
if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_MonoOut_StereoSamp_16BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_MonoOut_StereoSamp_16BitIn_NoTime;
}
}
else /* sample data mono */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_MonoOut_MonoSamp_16BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_MonoOut_MonoSamp_16BitIn_NoTime;
}
}
}
else /* 8-bit */
{
if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_MonoOut_StereoSamp_8BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_MonoOut_StereoSamp_8BitIn_NoTime;
}
}
else /* sample data mono */
{
if (Template->InterpolateThroughTime)
{
State->SampleGenSamples = Sample_MonoOut_MonoSamp_8BitIn_YesTime;
}
else
{
State->SampleGenSamples = Sample_MonoOut_MonoSamp_8BitIn_NoTime;
}
}
}
}
}
else
{
State->SampleGenSamples = Sample_NoOutput;
}
/* State->OverallLoudness, State->LeftLoudness, State->RightLoudness */
/* are determined by the envelope update */
StereoPosition += Template->StereoBias;
if (StereoPosition < -1)
{
StereoPosition = -1;
}
else if (StereoPosition > 1)
{
StereoPosition = 1;
}
State->Panning = Double2FastFixed(StereoPosition);
State->SampleLoudnessEnvelope = NewEnvelopeStateRecord(
Template->LoudnessEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,
InitialFrequency,1,HurryUp,Template->EnvelopeTicksPerSecond,&OnePreOrigin);
if (State->SampleLoudnessEnvelope == NIL)
{
FailurePoint2:
State->Next = SampleStateFreeList;
SampleStateFreeList = State;
goto FailurePoint1;
}
if (OnePreOrigin > MaxPreOrigin)
{
MaxPreOrigin = OnePreOrigin;
}
State->LoudnessLFOGenerator = NewLFOGenerator(Template->LoudnessLFOTemplate,
&OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
Template->EnvelopeTicksPerSecond,1,1,FreqForMultisampling);
/* I forgot what to pass in for the last 2 parameters */
if (State->LoudnessLFOGenerator == NIL)
{
FailurePoint3:
DisposeEnvelopeStateRecord(State->SampleLoudnessEnvelope);
goto FailurePoint2;
}
if (OnePreOrigin > MaxPreOrigin)
{
MaxPreOrigin = OnePreOrigin;
}
State->PitchLFO = NewLFOGenerator(Template->PitchLFOTemplate,
&OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
Template->EnvelopeTicksPerSecond,PitchDisplacementDepthLimit,
PitchDisplacementRateLimit,FreqForMultisampling);
if (State->PitchLFO == NIL)
{
FailurePoint4:
DisposeLFOGenerator(State->LoudnessLFOGenerator);
goto FailurePoint3;
}
if (OnePreOrigin > MaxPreOrigin)
{
MaxPreOrigin = OnePreOrigin;
}
State->PitchLFOStartCountdown = PitchDisplacementStartPoint;
*PreOriginTimeOut = MaxPreOrigin;
return State;
}
/* fix up pre-origin time for the sample state object */
void FixUpSampleStatePreOrigin(SampleStateRec* State,
long ActualPreOrigin)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
EnvelopeStateFixUpInitialDelay(State->SampleLoudnessEnvelope,ActualPreOrigin);
LFOGeneratorFixEnvelopeOrigins(State->LoudnessLFOGenerator,ActualPreOrigin);
LFOGeneratorFixEnvelopeOrigins(State->PitchLFO,ActualPreOrigin);
State->PreStartCountdown += ActualPreOrigin;
}
/* set a new frequency for a state object. used for portamento */
/* and modulation of frequency (vibrato) */
void SampleStateNewFrequency(SampleStateRec* State,
float NewFrequencyHertz)
{
double Differential;
CheckPtrExistence(State);
CheckValidSampleState(State);
if (State->PitchLFOStartCountdown > 0)
{
State->PitchLFOStartCountdown -= 1;
}
else
{
/* do some pitch stuff */
NewFrequencyHertz = FastFixed2Float(LFOGenUpdateCycle(State->PitchLFO,
Double2FastFixed(NewFrequencyHertz)));
}
Differential = ((NewFrequencyHertz * State->Template.FrequencyMultiplier
+ State->Template.FrequencyAdder) / State->NaturalFrequency)
/ State->Template.FinalOutputSamplingRate
* State->SamplingRate;
if (Differential < 0)
{
Differential = 0;
}
Double2LongLong(Differential,&(State->SamplePositionDifferential));
}
/* send a key-up signal to one of the oscillators */
void SampleKeyUpSustain1(SampleStateRec* State)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
LFOGeneratorKeyUpSustain1(State->LoudnessLFOGenerator);
EnvelopeKeyUpSustain1(State->SampleLoudnessEnvelope);
LFOGeneratorKeyUpSustain1(State->PitchLFO);
if (State->LoopState == eRepeatingLoop1)
{
if (State->Loop2Start != State->Loop2End)
{
State->LoopState = eRepeatingLoop2;
State->CurrentLoopEnd = State->Loop2End;
State->CurrentLoopLength = State->Loop2End - State->Loop2Start;
}
else if (State->Loop3Start != State->Loop3End)
{
State->LoopState = eRepeatingLoop3;
State->CurrentLoopEnd = State->Loop3End;
State->CurrentLoopLength = State->Loop3End - State->Loop3Start;
}
else
{
State->LoopState = eNoLoop;
State->CurrentLoopEnd = State->NumFrames;
State->CurrentLoopLength = 0;
}
}
}
/* send a key-up signal to one of the oscillators */
void SampleKeyUpSustain2(SampleStateRec* State)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
LFOGeneratorKeyUpSustain2(State->LoudnessLFOGenerator);
EnvelopeKeyUpSustain2(State->SampleLoudnessEnvelope);
LFOGeneratorKeyUpSustain2(State->PitchLFO);
if (/*(State->LoopState == eRepeatingLoop1)*/
/*||*/ (State->LoopState == eRepeatingLoop2))
{
if (State->Loop3Start != State->Loop3End)
{
State->LoopState = eRepeatingLoop3;
State->CurrentLoopEnd = State->Loop3End;
State->CurrentLoopLength = State->Loop3End - State->Loop3Start;
}
else
{
State->LoopState = eNoLoop;
State->CurrentLoopEnd = State->NumFrames;
State->CurrentLoopLength = 0;
}
}
}
/* send a key-up signal to one of the oscillators */
void SampleKeyUpSustain3(SampleStateRec* State)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
LFOGeneratorKeyUpSustain3(State->LoudnessLFOGenerator);
EnvelopeKeyUpSustain3(State->SampleLoudnessEnvelope);
LFOGeneratorKeyUpSustain3(State->PitchLFO);
if (/*(State->LoopState == eRepeatingLoop1)*/
/*|| (State->LoopState == eRepeatingLoop2)*/
/*||*/ (State->LoopState == eRepeatingLoop3))
{
State->LoopState = eNoLoop;
State->CurrentLoopEnd = State->NumFrames;
State->CurrentLoopLength = 0;
}
}
/* restart a sample oscillator. this is used for tie continuations */
void RestartSampleState(SampleStateRec* State,
float NewFreqMultisampling, float NewAccent1, float NewAccent2,
float NewAccent3, float NewAccent4, float NewLoudness,
float NewHurryUp, MyBoolean RetriggerEnvelopes,
float NewStereoPosition, float NewInitialFrequency,
float PitchDisplacementDepthLimit,
float PitchDisplacementRateLimit,
long PitchDisplacementStartPoint)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
NewStereoPosition += State->Template.StereoBias;
if (NewStereoPosition < -1)
{
NewStereoPosition = -1;
}
else if (NewStereoPosition > 1)
{
NewStereoPosition = 1;
}
State->Panning = Double2FastFixed(NewStereoPosition);
State->NoteLoudnessScaling = NewLoudness * State->Template.OverallOscillatorLoudness;
EnvelopeRetriggerFromOrigin(State->SampleLoudnessEnvelope,NewAccent1,NewAccent2,
NewAccent3,NewAccent4,NewInitialFrequency,1,NewHurryUp,
State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
LFOGeneratorRetriggerFromOrigin(State->LoudnessLFOGenerator,NewAccent1,
NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,1,1,
RetriggerEnvelopes);
LFOGeneratorRetriggerFromOrigin(State->PitchLFO,NewAccent1,
NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,
PitchDisplacementDepthLimit,PitchDisplacementRateLimit,
RetriggerEnvelopes);
if (RetriggerEnvelopes)
{
State->PitchLFOStartCountdown = PitchDisplacementStartPoint;
}
else
{
State->PitchLFOStartCountdown = -1;
}
}
/* generate a sequence of samples (called for each envelope clock) */
void SampleGenSamples(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
if (State->PreStartCountdown > 0)
{
return;
}
if (State->LoopState != eSampleFinished)
{
(*State->SampleGenSamples)(State,SampleCount,RawBuffer);
}
}
/* find out if the sample oscillator has finished */
MyBoolean SampleIsItFinished(SampleStateRec* State)
{
CheckPtrExistence(State);
CheckValidSampleState(State);
/* we are finished when one of the following conditions is met: */
/* - output volume is zero AND loudness envelope is finished */
/* - we have run off the end of the sample */
/* - we are not generating any signal */
if (!State->SampleWasDefined)
{
return True;
}
if (State->LoopState == eSampleFinished)
{
return True;
}
if (IsEnvelopeAtEnd(State->SampleLoudnessEnvelope))
{
if (State->Template.StereoPlayback == eSampleStereo)
{
if ((State->LeftLoudness == 0) && (State->RightLoudness == 0))
{
return True;
}
}
else
{
if (State->OverallLoudness == 0)
{
return True;
}
}
}
return False;
}
static void Sample_MonoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed char* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
*(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalOverallLoudness,
SampleData[LongLongHighHalf(LocalSamplePosition)]);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed char* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
signed long SamplePoint;
PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
SamplePoint = SampleData[LongLongHighHalf(LocalSamplePosition)];
*(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalLeftLoudness,SamplePoint);
*(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalRightLoudness,SamplePoint);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_MonoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed char* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
*(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalOverallLoudness,
((signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]
+ (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]) >> 1);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed char* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
*(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalLeftLoudness,
(signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]);
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
*(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalRightLoudness,
(signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_MonoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed short* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
SampleData[LongLongHighHalf(LocalSamplePosition)]);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed short* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
signed long SamplePoint;
PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
SamplePoint = SampleData[LongLongHighHalf(LocalSamplePosition)];
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,SamplePoint);
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,SamplePoint);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_MonoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed short* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
((signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]
+ (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]) >> 1);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed short* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,
(signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]);
PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,
(signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_MonoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed char* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
sizeof(SampleData[ArraySubscript]));
LeftValue = ((signed long)SampleData[ArraySubscript]) << 8; /* convert to 16-bit */
PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
sizeof(SampleData[ArraySubscript + 1]));
RightValue = ((signed long)SampleData[ArraySubscript + 1]) << 8; /* to 16-bit */
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed char* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
signed long CombinedValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
sizeof(SampleData[ArraySubscript]));
LeftValue = ((signed long)SampleData[ArraySubscript]) << 8; /* convert to 16-bit */
PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
sizeof(SampleData[ArraySubscript + 1]));
RightValue = ((signed long)SampleData[ArraySubscript + 1]) << 8; /* to 16-bit */
CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_MonoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed char* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 0]),
sizeof(SampleData[2 * ArraySubscript + 0]));
PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 1]),
sizeof(SampleData[2 * ArraySubscript + 1]));
LeftValue = ((signed long)SampleData[2 * ArraySubscript + 0]
+ (signed long)SampleData[2 * ArraySubscript + 1]) << 7; /* convert to 16-bit */
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 0]),
sizeof(SampleData[2 * (ArraySubscript + 1) + 0]));
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1) + 0]
+ (signed long)SampleData[2 * (ArraySubscript + 1) + 1]) << 7; /* to 16-bit */
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed char* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed char*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0)]),
sizeof(SampleData[2 * (ArraySubscript + 0)]));
LeftValue = ((signed long)SampleData[2 * (ArraySubscript + 0)]) << 8; /* convert to 16-bit */
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1)]),
sizeof(SampleData[2 * (ArraySubscript + 1)]));
RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1)]) << 8; /* to 16-bit */
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0) + 1]),
sizeof(SampleData[2 * (ArraySubscript + 0) + 1]));
LeftValue = ((signed long)SampleData[2 * (ArraySubscript + 0) + 1]) << 8; /* convert to 16-bit */
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1) + 1]) << 8; /* to 16-bit */
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_MonoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed short* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
sizeof(SampleData[ArraySubscript]));
LeftValue = SampleData[ArraySubscript];
PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
sizeof(SampleData[ArraySubscript + 1]));
RightValue = SampleData[ArraySubscript + 1];
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed short* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
signed long CombinedValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
sizeof(SampleData[ArraySubscript]));
LeftValue = SampleData[ArraySubscript];
PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
sizeof(SampleData[ArraySubscript + 1]));
RightValue = SampleData[ArraySubscript + 1];
CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_MonoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalOverallLoudness;
signed short* SampleData;
LocalOverallLoudness = State->OverallLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 0]),
sizeof(SampleData[2 * ArraySubscript + 0]));
PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 1]),
sizeof(SampleData[2 * ArraySubscript + 1]));
LeftValue = ((signed long)SampleData[2 * ArraySubscript + 0]
+ (signed long)SampleData[2 * ArraySubscript + 1]) >> 1;
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 0]),
sizeof(SampleData[2 * (ArraySubscript + 1) + 0]));
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1) + 0]
+ (signed long)SampleData[2 * (ArraySubscript + 1) + 1]) >> 1;
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_StereoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
LongLongRec LocalSamplePosition;
LongLongRec LocalSamplePositionDifferential;
long LocalCurrentLoopEnd;
FastFixedType LocalLeftLoudness;
FastFixedType LocalRightLoudness;
signed short* SampleData;
LocalLeftLoudness = State->LeftLoudness;
LocalRightLoudness = State->RightLoudness;
LocalSamplePosition = State->SamplePosition;
LocalSamplePositionDifferential = State->SamplePositionDifferential;
LocalCurrentLoopEnd = State->CurrentLoopEnd;
SampleData = (signed short*)State->Data;
while (SampleCount > 0)
{
FastFixedType LeftWeight;
long ArraySubscript;
signed long LeftValue;
signed long RightValue;
/* L+F(R-L) */
LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
ArraySubscript = LongLongHighHalf(LocalSamplePosition);
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0)]),
sizeof(SampleData[2 * (ArraySubscript + 0)]));
LeftValue = SampleData[2 * (ArraySubscript + 0)];
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1)]),
sizeof(SampleData[2 * (ArraySubscript + 1)]));
RightValue = SampleData[2 * (ArraySubscript + 1)];
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0) + 1]),
sizeof(SampleData[2 * (ArraySubscript + 0) + 1]));
LeftValue = SampleData[2 * (ArraySubscript + 0) + 1];
PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
RightValue = SampleData[2 * (ArraySubscript + 1) + 1];
*(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,LeftValue
+ ((LeftWeight * (RightValue - LeftValue)) >> 15));
LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
CheapDoLoop:
if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
{
if (State->LoopState != eNoLoop)
{
/* handle loop */
LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
LocalSamplePosition) - State->CurrentLoopLength);
goto CheapDoLoop;
}
else
{
/* end of sample -- terminate */
State->LoopState = eSampleFinished;
goto BreakLoopPoint;
}
}
SampleCount -= 1;
}
BreakLoopPoint:
;
State->SamplePosition = LocalSamplePosition;
}
static void Sample_NoOutput(SampleStateRec* State,
long SampleCount, largefixedsigned* RawBuffer)
{
}